#include <everest/dbc/odbc/odbc_common.h>
#include <vector>
#include <string.h>

using namespace everest::dbc::odbc;
using namespace everest::dbc;
using namespace std;

OdbcEnvironment::OdbcEnvironment() : m_EnvHandle(SQL_NULL_HANDLE)
{
	SQLRETURN result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_EnvHandle);

	SQLPOINTER ver = (SQLPOINTER)SQL_OV_ODBC3;
	result = SQLSetEnvAttr(m_EnvHandle, SQL_ATTR_ODBC_VERSION, ver, 0);
	if ( result == SQL_ERROR )
		throw OdbcException(SQL_HANDLE_ENV, m_EnvHandle, "OdbcEnvironment::OdbcEnvironment()");
}

OdbcEnvironment::~OdbcEnvironment()
{
	if ( m_EnvHandle != SQL_NULL_HANDLE) {
		SQLFreeHandle(SQL_HANDLE_ENV, m_EnvHandle);
	}
	m_EnvHandle = SQL_NULL_HANDLE;
}

IConnection * OdbcEnvironment::createConnection(const char *pszConStr)
{
	if ( m_EnvHandle == SQL_NULL_HANDLE ) {
		throw OdbcException::InvalidHandle(SQL_HANDLE_ENV, m_EnvHandle, "OdbcEnvironment::createConnection");
	}

	SQLHANDLE hConn = SQL_NULL_HANDLE;
	SQLRETURN result = SQLAllocHandle(SQL_HANDLE_DBC, m_EnvHandle, &hConn);
	if ( result == SQL_ERROR ) throw OdbcException(SQL_HANDLE_ENV, m_EnvHandle, "OdbcEnvironment::createConnection{1}");
	SQLSMALLINT len = strlen(pszConStr);
	SQLSMALLINT olen = 0;

	vector<SQLCHAR> inbuf;
	inbuf.reserve(len + 1);
	strcpy((char *)&inbuf[0], pszConStr);

	result = SQLDriverConnect(hConn, NULL, &inbuf[0], len, NULL, 0, &olen, SQL_DRIVER_NOPROMPT);
	if ( result == SQL_ERROR ) throw OdbcException(SQL_HANDLE_DBC, hConn, "OdbcEnvironment::createConnection{2}");

	return new OdbcConnection(hConn);
}

